import org.devops.Constants
import org.devops.deploy
import org.devops.nodeTools
import org.devops.record

def call(Map map) {
    def record = new record()
    def nodeTools = new nodeTools()
    def deploy = new deploy()

    def execTime = nodeTools.getNowTime()
    String VALUES_URL = Constants.VALUES_URL
    String HARBOR_PROJECT = Constants.HARBOR_PROJECT
    String JENKINS_DOCKERFILES_DIR = Constants.JENKINS_DOCKERFILES_DIR
    println(map.get("GIT_CREDENTIAL_ID"))
    String GIT_CREDENTIAL_ID = map.get("GIT_CREDENTIAL_ID") ?: Constants.GIT_CREDENTIAL_ID
    String VERSION = Constants.VERSION
    String NODE_VERSOIN = map.get("NODE_VERSION") ?: "node14.15"
    String SOURCE = map.get("COMPILED_DIR") ?: "dist"
    String TARGET = "dist.tar"
    String BRANCH_FILTER = Constants.DEFAULT_BRANCH_FILTER
    String RUN_IMAGE = map.get("RUN_IMAGE") ?: "harbor.ops.xjjtkj.cn/library/nginx:1.22.0"
    if (map.get("P_ENV") == "prod") {
        BRANCH_FILTER = map.get("PROD_BRANCH_FILTER") ?: Constants.PROD_BRANCH_FILTER
    }
    String NAMESPACE = map.get("P_SERVICE") + "-" + map.get("P_ENV")
    String DEFAULT_CLUSTER = "xjt_" + map.get("P_ENV")
    String CLUSTER_NAME = map.get("CLUSTER_NAME") ?: (Constants.SPECIAL_SERVICE.contains(NAMESPACE) ? NAMESPACE : DEFAULT_CLUSTER)

    def COMPILE_COMMAND = map.get("COMPILE_COMMAND")
    def ZIP_FILE = map.get("ZIP_FILE") ?: "dist.zip"
    def EXEC_DIR = map.get("EXEC_DIR") ?: "./"
    def ROLLBACK_VARIABLES_BINDINGS = "JOB_NAME=${JOB_NAME}"

    pipeline {
        agent any
        environment {
            GIT_URL = map.get("GIT_URL")
            ENV = map.get("P_ENV")
            SERVICE = map.get("P_SERVICE")
        }
        parameters {
            extendedChoice(defaultValue: map.P_DEFAULT_BUILD_APPS, description: '应用名', multiSelectDelimiter: ',', name: 'BUILD_APPS', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_CHECKBOX', value: map.P_BUILD_APPS, visibleItemCount: 5)
            gitParameter(branch: '', branchFilter: BRANCH_FILTER, defaultValue: 'origin/master', description: '分支', name: 'BRANCH', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'GitParameterDefinition', useRepository: map.GIT_URL)
            booleanParam(defaultValue: true, description: '是否部署', name: 'DEPLOY')
            choice(choices: ['deploy', 'rollback', 'init'], description: '模式', name: 'MOD')
            extendedChoice(bindings: ROLLBACK_VARIABLES_BINDINGS, groovyClasspath: '', groovyScript: Constants.ROLLBACK_SCRIPT, description: '回滚版本,只显示最近5次发布记录,倒序排列,只有在MOD为rollback时生效', multiSelectDelimiter: ',', name: 'ROLLBACK_VERSION', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_SINGLE_SELECT', visibleItemCount: 5)
        }
        options {
            timestamps() // 输出构建日志打印时间信息
            timeout(time: 60, unit: 'MINUTES') // 设置构建超时时间
            buildDiscarder(logRotator(numToKeepStr: '5')) // 设置历史构建保留次数
        }
        stages {
            stage('git clone') {
                steps {
                    script {
                        String branch = "$BRANCH".replaceAll("origin/", "")
                        git branch: "${branch}", credentialsId: "${GIT_CREDENTIAL_ID}", url: "${GIT_URL}"
                    }
                }
            }
            stage('编译') {
                when {
                    environment name: 'MOD', value: 'deploy'
                }
                steps {
                    script {
                        dir(EXEC_DIR) {
                            //编译之前删除zip压缩包
                            if (fileExists(ZIP_FILE) && !ZIP_FILE.startsWith("/")) {
                                sh "rm -f ${ZIP_FILE}"
                            }
                            nodejs("${NODE_VERSOIN}") {
                                for (command in COMPILE_COMMAND) {
                                    sh "${command}"
                                }
                            }
                        }
                    }
                }
            }
            stage('编译镜像,部署') {
                when {
                    environment name: 'MOD', value: 'deploy'
                }
                steps {
                    script {
                        dir(EXEC_DIR) {
                            String branch = "$BRANCH".replaceAll("origin/", "").replaceAll("_", "-").replaceAll("/", "-")
                            String commit = sh(returnStdout: true, script: "git rev-parse --short HEAD").trim()

                            def a = "${params.BUILD_APPS}"
                            echo "2.拼接${a}项目镜像地址"
                            def IMAGE_PRIFIX = "${HARBOR_PROJECT}/$SERVICE/$a".toLowerCase()
                            def IMAGE_TAG = "${branch}-${commit}-$BUILD_NUMBER".toLowerCase()
                            def IMAGE_NAME = "${IMAGE_PRIFIX}:${IMAGE_TAG}"
                            echo "项目${a}镜像名称: $IMAGE_NAME"

                            echo "3.项目$a docker编译"
                            if (fileExists(ZIP_FILE) && !fileExists(SOURCE)) {
                                sh "unzip ${ZIP_FILE}"
                            }

                            if (!fileExists(SOURCE)) {
                                echo "未找到${SOURCE}，请确定${SOURCE}目录是否存在"
                                error "未找到${SOURCE}，请确定${SOURCE}目录是否存在"
                            }

                            sh """mkdir -p ${JENKINS_DOCKERFILES_DIR}"""
                            sh """tar -cf ${JENKINS_DOCKERFILES_DIR}/${TARGET} ${SOURCE}"""
                            defineDockerfile(RUN_IMAGE, "${JENKINS_DOCKERFILES_DIR}", a, "${TARGET}")
                            sh """docker build -t $IMAGE_NAME -f $JENKINS_DOCKERFILES_DIR/$a  ${JENKINS_DOCKERFILES_DIR}"""

                            echo "4.项目$a docker 上传"
                            sh """docker push  $IMAGE_NAME"""

                            if (params.DEPLOY) {
                                deploy.deployK8sApp(CLUSTER_NAME, a, JENKINS_DOCKERFILES_DIR, VALUES_URL, IMAGE_PRIFIX, IMAGE_TAG, VERSION)
                            }

                            //上传部署信息到project-info(记录每次部署信息)服务上,并将返回结果拼接成需要删除的node
                            record.recordImageProjectInfo(execTime, Constants.PROJECT_BASE_URL, BUILD_APPS, "")
                        }
                    }
                }
            }
            stage("回滚") {
                when {
                    environment name: 'MOD', value: 'rollback'
                }
                steps {
                    script {
                        def rollbackVersion = "${params.ROLLBACK_VERSION}"
                        def split = rollbackVersion.split("\\|")
                        if (split.size() == 0) {
                            error "请选择要回滚的版本"
                        }

                        def r = record.getProjectInfoByBuildNumber(Constants.PROJECT_BASE_URL, split[0])
                        def buildNumber = r.build_number
                        def apps = r.app
                        def branch = r.branch
                        def commit = r.commit
                        def IMAGE_TAG = "${branch}-${commit}-$buildNumber".toLowerCase()

                        echo "BUILD_APPS: ${BUILD_APPS}"
                        echo "apps: ${apps}"
                        echo "branch: ${branch}"
                        echo "commit: ${commit}"

                        def noContains = []
                        for (a in BUILD_APPS.tokenize(',')) {
                            if (!apps.contains(a)) {
                                noContains.add(a)
                            }
                        }

                        if (noContains.size() > 0) {
                            error "选择回滚版本不包含,服务${noContains}"
                        }

                        for (a in BUILD_APPS.tokenize(',')) {
                            def appName = a.replaceAll("-1.0.0.RELEASE", "")
                            def IMAGE_PRIFIX = "${HARBOR_PROJECT}/$SERVICE/$appName".toLowerCase()

                            deploy.deployK8sApp(CLUSTER_NAME, appName, JENKINS_DOCKERFILES_DIR, VALUES_URL, IMAGE_PRIFIX, IMAGE_TAG, VERSION)
                        }
                    }
                }
            }
        }
    }
}

def defineDockerfile(RUN_IMAGE, jenkinsDockerfileDir, app, target) {
    String path = jenkinsDockerfileDir + "/" + app
    String dockerfile = '''    
FROM $RUN_IMAGE

ADD $TARGET /usr/share/nginx/html/
'''

    dockerfile = dockerfile.replace("\$RUN_IMAGE", RUN_IMAGE).replace("\$TARGET", target)
    writeFile file: "${path}", text: "${dockerfile}"
}
